#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "TcpConnection.h"
#include "Log.h"

int32_t processRead(void *arg)
{
    struct TcpConnection *conn = (struct TcpConnection *)arg;

    // 接收数据
    int32_t count = bufferSocketRead(conn->readBuff, conn->channel->fd);
    if (count > 0)
    {   
        printf("processRead 函数调用 cfd = %d\n", conn->channel->fd);
        printf("bufferSocketRead 函数调用 cfd = %d 读取count = %d\n", conn->channel->fd, count);
        char *tmp = (char *)malloc(count);
        strncpy(tmp, conn->readBuff->data + conn->readBuff->readPos, count);
        printf("读取count = %d 内容：%s\n", count, tmp);
        free(tmp);
        // 接收到了http请求,解析http请求
        int32_t socket = conn->channel->fd;
#ifdef MSG_SEND_AUTO
        writeEventEnable(conn->channel, true);
        eventLoopAddTask(conn->evLoop, conn->channel, MODIFY);
#endif
        bool flag = parseHttpRequest(conn->request, conn->readBuff, conn->response, conn->writeBuff, socket);
        if (!flag)
        {
            // 解析失败,回复一个简单的html
            char *errMsg = "Http/1.1 400 Bad Request\r\n\r\n";
            bufferAppendString(conn->writeBuff, errMsg);
        }
    }
    // else if(count == 0)
    // {
    //     printf("删除 fd = %d \n", conn->channel->fd);
    //     eventLoopAddTask(conn->evLoop, conn->channel, DELECT);
    // }
}

int32_t processWrite(void *arg)
{
    printf("processWrite 函数调用\n");
    struct TcpConnection *conn = (struct TcpConnection *)arg;
    // 发送数据
    int32_t count = bufferSendData(conn->writeBuff, conn->channel->fd);
    if (count > 0)
    {
        // 判断数据是否全部发送出去了
        if (bufferReadableSize(conn->writeBuff) == 0)
        {
            // 1.不再检测写事件 -- 修改channel中保存的事件
            writeEventEnable(conn->channel, false);
            // 2.修改dispatcher检测的集合 -- 添加任务节点
            eventLoopAddTask(conn->evLoop, conn->channel, MODIFY);
            // 3.删除这个节点
            eventLoopAddTask(conn->evLoop, conn->channel, DELECT);
        }
    }
    else
    {
        eventLoopAddTask(conn->evLoop, conn->channel, DELECT);
    }
}

struct TcpConnection *TcpConnectionInit(int32_t fd, struct EventLoop *evLoop)
{
    struct TcpConnection *conn = (struct TcpConnection *)malloc(sizeof(struct TcpConnection));
    conn->evLoop = evLoop;
    conn->request = httpRequestInit();
    conn->response = httpResponseInit();
    conn->readBuff = bufferInit(10240);
    conn->writeBuff = bufferInit(10240);
    snprintf(conn->name, sizeof(conn->name), "Connecttion-%d", fd);
    conn->channel = channelInit(fd, ReadEvent, processRead, processWrite, TcpConnectionDestroy, conn);

    eventLoopAddTask(evLoop, conn->channel, ADD);
    return conn;
}

int TcpConnectionDestroy(void *arg)
{
    struct TcpConnection *conn = (struct TcpConnection *)arg;
    if (conn != NULL)
    {
        if (conn->readBuff && bufferReadableSize(conn->readBuff) == 0 &&
            conn->writeBuff && bufferReadableSize(conn->writeBuff) == 0)
        {
            destroyChannel(conn->evLoop, conn->channel);
            bufferDestroy(conn->readBuff);
            bufferDestroy(conn->writeBuff);
            httpRequestDestroy(conn->request);
            httpResponseDestory(conn->response);
            free(conn);
            return 0;
        }
    }
    return -1;
}
